﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using Pixysoft.Framework.Logs;
using Pixysoft.Framework.Verifications;

namespace Pixysoft.Framework.Logs.Controller
{
    class SettingController
    {
        private static readonly System.Threading.ReaderWriterLock locker = new ReaderWriterLock();

        List<LoggerSetting> settings = new List<LoggerSetting>();

        private static volatile SettingController instance;

        private static object syncRoot = new Object();

        public static SettingController Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (syncRoot)
                    {
                        instance = new SettingController();
                    }
                }

                return instance;

            }
        }

        public static void Initialize(LogConfiguration config)
        {
            config.Verify();

            Instance.settings.Clear();

            LoggerSetting rootSetting = new LoggerSetting();
            rootSetting.Filename = config.Filename;
            rootSetting.LogCapacity = config.LogCapacity;
            rootSetting.LogLevel = config.LogLevel;
            rootSetting.LogPath = config.LogPath;
            rootSetting.Modulename = config.Modulename;
            rootSetting.PrintToConsole = config.PrintToConsole;

            Instance.settings.Add(rootSetting);

            foreach (LoggerSetting setting in config.Settings)
            {
                Instance.settings.Add(setting);
            }
        }

        /// <summary>
        /// 获取明细配置 如果存在基本配置 则拷贝基本配置后得到明细配置
        /// 输入filename/modulename不允许null 
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="modulename"></param>
        /// <returns></returns>
        public LoggerSetting getSetting(string filename, string modulename)
        {
            if (filename == null || modulename == null)
                throw Exceptions.VerificationFailedException(filename, modulename);


            filename = StringFilter.GetFileName(filename);

            //因为getsetting在初始化的时候调用，因此实际上filepath没有参与运算，这个值是初始化之后获取了setting才设置的。所以没有影响

            locker.AcquireWriterLock(Timeout.Infinite);

            try
            {
                LoggerSetting setting = getSingleSetting(filename, modulename);

                if (setting != null)
                    return setting;

                setting = new LoggerSetting();

                setting.Filename = filename;

                setting.LogPath = StringHelper.default_log_filepath;

                LoggerSetting rootSetting = getRootSetting(filename);

                if (rootSetting == null)
                {
                    rootSetting = getRootSetting();
                }

                if (rootSetting != null)
                {
                    setting.LogLevel = rootSetting.LogLevel;

                    setting.PrintToConsole = rootSetting.PrintToConsole;

                    setting.LogCapacity = rootSetting.LogCapacity;
                }

                settings.Add(setting);

                return setting;
            }
            finally
            {
                locker.ReleaseWriterLock();
            }
        }

        /// <summary>
        /// 获取集合配置 用于统一设置
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        public GroupLoggerSetting getGroupSetting(string filename)
        {
            List<ILoggerSetting> list = new List<ILoggerSetting>();

            locker.AcquireWriterLock(Timeout.Infinite);

            try
            {
                foreach (LoggerSetting setting in settings)
                {
                    if (string.Equals(setting.Filename, filename, StringComparison.OrdinalIgnoreCase))
                        list.Add(setting);
                }

                return new GroupLoggerSetting(list);
            }
            finally
            {
                locker.ReleaseWriterLock();
            }
        }

        /// <summary>
        /// 获取明细配置
        /// </summary>
        /// <param name="filename"></param>
        /// <param name="modulename"></param>
        /// <returns></returns>
        private LoggerSetting getSingleSetting(string filename, string modulename)
        {
            foreach (LoggerSetting setting in settings)
            {
                if (!string.Equals(setting.Filename, filename, StringComparison.OrdinalIgnoreCase))
                    continue;

                if (!string.Equals(setting.Modulename, modulename, StringComparison.OrdinalIgnoreCase))
                    continue;

                return setting;
            }

            return null;
        }

        private LoggerSetting getRootSetting(string filename)
        {
            foreach (LoggerSetting setting in settings)
            {
                if (!string.Equals(setting.Filename, filename, StringComparison.OrdinalIgnoreCase))
                    continue;

                if (!string.IsNullOrEmpty(setting.Modulename))
                    continue;

                return setting;
            }

            return null;
        }

        private LoggerSetting getRootSetting()
        {
            return getRootSetting(StringHelper.default_log_prefix);
        }
    }
}
